home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / dev / c / vbccm68ksrc.lha / vbcc / vlink / t_amigaos.c < prev    next >
C/C++ Source or Header  |  1999-03-07  |  47KB  |  1,515 lines

  1. /* $VER: vlink t_amigaos.c V0.6c (05.02.99)
  2.  *
  3.  * This file is part of vlink, a portable linker for multiple
  4.  * object formats.
  5.  * Copyright (c) 1997-99  Frank Wille
  6.  *
  7.  * vlink is freeware and part of the portable and retargetable ANSI C
  8.  * compiler vbcc, copyright (c) 1995-99 by Volker Barthelmann.
  9.  * vlink may be freely redistributed as long as no modifications are
  10.  * made and nothing is charged for it. Non-commercial usage is allowed
  11.  * without any restrictions.
  12.  * EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE
  13.  * SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR.
  14.  *
  15.  *
  16.  * v0.6c (05.02.98) phx
  17.  *       __ctors/__dtors for executables only.
  18.  * v0.6a (19.12.98) phx
  19.  *       Support for little endian object file formats.
  20.  * v0.6  (24.10.98) phx
  21.  *       Take base register section offset from FFFuncs.baseoff.
  22.  * v0.5f (08.10.98) phx
  23.  *       The automatic constructor/destructor functions have to begin
  24.  *       with __INIT or __EXIT to avoid conflicts with ANSI-C identifiers.
  25.  * v0.5e (05.10.98) phx
  26.  *       Global symbols beginning with _INIT or _EXIT will create an
  27.  *       entry into the constructor/destructor function pointer table.
  28.  *       These tables can be addressed by using the symbols __ctors
  29.  *       and __dtors (e.g. in the startup/cleanup code of a program).
  30.  *       The priority of these functions may be defined by specifying
  31.  *       a number behind the INIT/EXIT string. Example: _INIT_9_OpenLibs.
  32.  *       Otherwise their priority defaults to 0 and they will be
  33.  *       positioned in order of occurence.
  34.  * v0.5d (22.08.98) phx
  35.  *       Faster memory allocation can be activated by #define FASTALLOC.
  36.  * v0.5c (08.07.98) phx
  37.  *       ehf_lnksym():
  38.  *       Target amigaehf supports the automatic generation of "@__name"
  39.  *       pointer variables in ".tocd". @__name will not be created, if
  40.  *       _name is undefined too. Then it's assumed to be a real unknown
  41.  *       symbol reference.
  42.  * v0.5  (27.06.98) phx
  43.  *       Target-specific linker symbol support: ados_lnksym(), ehf_lnksym(),
  44.  *       ados_setlnksym(), ehf_setlnksym().
  45.  *       Linker symbols currently supported by ADOS and EHF:
  46.  *       _DATA_BAS_,_DATA_LEN_,_BSS_LEN_,_LinkerDB,__BSSBAS,__BSSLEN,
  47.  *       __ctors,__dtors,__DATA_BAS,__DATA_LEN,__BSS_LEN,__RESIDENT.
  48.  * v0.4  (05.06.98) phx
  49.  *       Support for Code-Bss and Data-Bss (small data) sections.
  50.  *       New FFF targetlink(). Checks for __MERGED, _NOMERGE and
  51.  *       unnamed sections.
  52.  * v0.3b (02.05.98) phx
  53.  *       Creates a dummy code section, if an output file has no
  54.  *       section at all.
  55.  * v0.3  (12.04.98) phx
  56.  *       fwrite32() is now called as fwrite32be().
  57.  *       Uses new addreloc() from targets.c.
  58.  *       addxref() requires addend.
  59.  *       Ignore absolute local symbols for object files and ignore
  60.  *       absolute local and global symbols for executable files.
  61.  * v0.2  (07.03.98) phx
  62.  *       Unnamed sections of an executable will always get different
  63.  *       names, to avoid that they are linked together.
  64.  *       HUNK_DREL32 must be treated as HUNK_RELOC32SHORT, if the
  65.  *       input file is executable.
  66.  *       Number of hunks in HUNK_HEADER was wrong, if resident library
  67.  *       name is missing (which is always the case).
  68.  * v0.1  (27.02.98) phx
  69.  *       First version that seems to link AmigaOS ADOS and EHF
  70.  *       objects and libraries. Many common features, like linking
  71.  *       sections together which have relative references, are
  72.  *       still missing. Also, PowerPC-ELF32 support is about to come.
  73.  * v0.0  (02.12.97) phx
  74.  *       File created.
  75.  */
  76.  
  77.  
  78. #if defined(ADOS) || defined(EHF)
  79. #define T_AMIGAOS_C
  80. #include "vlink.h"
  81. #include "amigahunks.h"
  82.  
  83. #define BSSDEFAULTNAME "BSS"
  84. #define EXT_IGNORE 0x100
  85.  
  86. struct HunkInfo {
  87.   uint8 *hunkbase;  /* base address of amigaos/ehf file */
  88.   uint8 *hunkptr;   /* current hunk data pointer */
  89.   long hunkcnt;     /* remaining bytes in this file */
  90.   char *filename;
  91.   bool exec;        /* executable file? */
  92. };
  93.  
  94. struct XRefNode {
  95.   struct node n;
  96.   char *sym_name;
  97.   uint8 ref_type;
  98.   int noffsets;
  99.   struct list xreflist;
  100. };
  101.  
  102.  
  103. static int ados_identify(char*,uint8 *,unsigned long);
  104. static int ehf_identify(char *,uint8 *,unsigned long);
  105. static int identify(char *,uint8 *,unsigned long);
  106. static void readconv(struct GlobalVars *,struct LinkFile *);
  107. static unsigned long secbase(struct GlobalVars *,char *);
  108. static uint8 cmpsecflags(uint8,uint8);
  109. static struct Section *bssdefault(struct ObjectUnit *);
  110. static int targetlink(struct GlobalVars *,struct LinkedSection *,
  111.                       struct Section *);
  112. static struct Symbol *ados_lnksym(struct GlobalVars *,struct Section *,
  113.                                   struct XReference *);
  114. static void ados_setlnksym(struct GlobalVars *,struct Symbol *,
  115.                            struct XReference *);
  116. static struct Symbol *ehf_lnksym(struct GlobalVars *,struct Section *,
  117.                                   struct XReference *);
  118. static void ehf_setlnksym(struct GlobalVars *,struct Symbol *,
  119.                            struct XReference *);
  120. static int get_xtors_pri(char *);
  121. static void create_xdef(struct GlobalVars *,struct Section *,char *,
  122.                         uint32,uint8,uint8);
  123. static void create_xrefs(struct GlobalVars *,struct HunkInfo *,
  124.                          struct Section *,char *,uint8,uint8);
  125. static char *gethunkname(struct HunkInfo *);
  126. static bool addlongrelocs(struct GlobalVars *,struct HunkInfo *,
  127.                           struct Section *,uint8);
  128. static bool addshortrelocs(struct GlobalVars *,struct HunkInfo *,
  129.                            struct Section *,uint8);
  130. static void init_hunkinfo(struct HunkInfo *,char *,uint8 *,unsigned long);
  131. static uint32 skiphunk(struct HunkInfo *);
  132. static void movehunkptr32(struct HunkInfo *,uint32);
  133. static void movehunkptr16(struct HunkInfo *,uint32);
  134. static void alignhunkptr(struct HunkInfo *);
  135. static uint32 testword32(struct HunkInfo *);
  136. static uint32 nextword32(struct HunkInfo *);
  137. static uint16 nextword16(struct HunkInfo *);
  138. static void writeobject(struct GlobalVars *,FILE *);
  139. static void writeshared(struct GlobalVars *,FILE *);
  140. static void writeexec(struct GlobalVars *,FILE *);
  141. static void hunk_name_len(FILE *,char *);
  142. static void hunk_name(FILE *,char *);
  143. static int strlen32(char *);
  144. static void reloc_hunk(FILE *,struct LinkedSection *,struct GlobalVars *,
  145.                        uint8,uint32);
  146. static void unsupp_relocs(struct LinkedSection *);
  147. static void ext_refs(FILE *,struct LinkedSection *);
  148. static void ext_defs(FILE *,struct LinkedSection *,uint8,uint8,uint32);
  149. static void unsupp_symbols(struct LinkedSection *);
  150.  
  151.  
  152. struct FFFuncs fff_amigaos = {
  153.   "amigaos",
  154.   ados_identify,
  155.   readconv,
  156.   secbase,
  157.   cmpsecflags,
  158.   bssdefault,
  159.   targetlink,
  160.   ados_lnksym,
  161.   ados_setlnksym,
  162.   writeobject,
  163.   writeshared,
  164.   writeexec,
  165.   0x7ffe,
  166.   NULL,
  167.   1 /* big endian */
  168. };
  169.  
  170. struct FFFuncs fff_ehf = {
  171.   "amigaehf",
  172.   ehf_identify,
  173.   readconv,
  174.   secbase,
  175.   cmpsecflags,
  176.   bssdefault,
  177.   targetlink,
  178.   ehf_lnksym,
  179.   ehf_setlnksym,
  180.   writeobject,
  181.   writeshared,
  182.   writeexec,
  183.   0x7ffe,
  184.   NULL,
  185.   1 /* big endian */
  186. };
  187.  
  188. /* Automagically create symbols in .tocd, which start with the */
  189. /* following letters: */
  190. static char ehf_addrsym[] = "@_";
  191.  
  192. static char *ados_symnames[] = {
  193.   /* PhxAss */     "_DATA_BAS_","_DATA_LEN_","_BSS_LEN_",
  194.   /* SAS/StormC */ "_LinkerDB","__BSSBAS","__BSSLEN","__ctors","__dtors",
  195.   /* DICE-C */     "__DATA_BAS","__DATA_LEN","__BSS_LEN","__RESIDENT"
  196. };
  197. #define PHXDB 0
  198. #define PHXDL 1
  199. #define PHXBL 2
  200. #define SASPT 3
  201. #define SASBB 4
  202. #define SASBL 5
  203. #define SASCT 6
  204. #define SASDT 7
  205. #define DICDB 8
  206. #define DICDL 9
  207. #define DICBL 10
  208. #define DICRS 11
  209. #define LAST_LNKSYM DICRS
  210.  
  211. /* automatic constructors and destructors */
  212. static char vbcc_INIT[] = "__INIT";
  213. static char vbcc_EXIT[] = "__EXIT";
  214. static char xtors_objname[] = "INITEXIT"; /* unit name for con/destructors */
  215.  
  216. static bool exthunk,symhunk;
  217.  
  218.  
  219.  
  220. /*****************************************************************/
  221. /*                      Read ADOS / EHF                          */
  222. /*****************************************************************/
  223.  
  224.  
  225. static int ados_identify(char *name,uint8 *p,